/**
 * @file main.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
//如果宏 _DEFAULT_SOURCE 没定义那就定义它
#ifndef _DEFAULT_SOURCE
    //_DEFAULT_SOURCE 是 GNU C 库（glibc） 提供的一个特性测试宏（Feature Test Macro）。
    //C 标准库函数不是所有都默认启用，有些函数（例如 usleep()、strdup()、getline()）属于 POSIX 或 GNU 扩展；
    //需要宏定义特性测试宏（Feature Test Macro）来控制哪些 POSIX、BSD 或 GNU 扩展函数在头文件中可见。
    //如果没有定义它，unistd.h 不会暴露 usleep() 的声明，导致调用函数时报错：❌error: implicit declaration of function ‘usleep’
    //✅有包含头文件#include <unistd.h>并调用usleep(1000);就需要定义它
    #define _DEFAULT_SOURCE /* needed for usleep() */
#endif

#include <stdlib.h>
#include <stdio.h>
// Visual Studio在Windows下编译的情况下会定义这个宏，以此判断是否为Windows平台
// 否则是其他系统（例如 Linux、macOS）
#ifdef _MSC_VER
  #include <Windows.h>
#else
  #include <unistd.h>
  #include <pthread.h>
#endif
#include "lvgl/lvgl.h"
#include "lvgl/examples/lv_examples.h"
#include "lvgl/demos/lv_demos.h"
// #include <SDL.h>
#include "../library/hal/hal.h"

#include "../config/CustomConfig.h"
#include "home/home.h"
#include "utils/components/sdl_disp_window.h"
#include "utils/file_util/file_util.h"

/*********************
 *      DEFINES
 *********************/

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/

/**********************
 *  STATIC VARIABLES
 **********************/

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
 **********************/

// ✅LV_USE_OS宏定义，当前项目使用的操作系统（RTOS）是哪种 OS
// 宏值	                含义	                    说明
// LV_OS_NONE	        无操作系统（裸机），           值为0，适用于 PC 模拟、STM32 单片机裸机
// LV_OS_FREERTOS	    使用 FreeRTOS，             值为1，常见于嵌入式项目
// LV_OS_PTHREAD	    使用 pthread（POSIX 线程），  值为2，Linux 或 macOS 上运行
// LV_OS_CMSIS_RTOS2	使用 CMSIS RTOS v2，        值为3，常见于 ARM 环境
// LV_OS_RTTHREAD	    使用 RT-Thread，            值为4， 实时系统	国产 RTOS 环境

// 当前项目使用的操作系统（RTOS）是否为FreeRTOS（即单片机或 PC 模拟环境）
#if LV_USE_OS != LV_OS_FREERTOS
    int main(int argc, char **argv)
    {

        (void)argc; /*Unused*/
        (void)argv; /*Unused*/
        //文件存储处理
        ensure_data_dir_exists();

        /*初始化 LVGL 内核，Initialize LVGL*/
        lv_init();
        /*初始化一个基于 SDL 的硬件抽象层（HAL），在电脑上模拟一个 320×480 的 GUI 窗口。
        Initialize the HAL (display, input devices, tick) for LVGL*/
        // sdl_hal_init(320, 480);
        home_disp = sdl_hal_init(DISP_WIDTH, DISP_HEIGHT);
        set_window_title(home_disp, "Home");

        /* Run the default demo */
        /* To try a different demo or example, replace this with one of: */
        /* - lv_demo_benchmark(); */
        /* - lv_demo_stress(); */
        /* - lv_example_label_1(); */
        /* - etc. */
        /* - lv_demo_widgets();//lvgl demo */

        /* 显示 home 界面 */
        //通过lv_scr_act()得到的不是lv_sdl_window_create创建的disp显示设备对象，而是disp上的当前屏幕screen
        home_screen = lv_scr_act();//通过lv_scr_act()方法获取主屏幕当前活动屏幕
        printf("main: start config home ui\n");
        lv_home_ui();

        // 主循环：
        while(1) {
            /* Periodically call the lv_task handler.
            * It could be done in a timer interrupt or an OS task too.
            不断调用 lv_timer_handler() 处理 UI 更新；*/
            //返回值是一个建议的休眠时间（毫秒），有动画返回10，没有任务要执行，返回 100；如果需要立即刷新（比如刚点击按钮），返回 0。
            uint32_t sleep_time_ms = lv_timer_handler();
            //判断返回值是否为LV_NO_TIMER_READY，即当前没有任何定时任务需要执行，值为0xFFFFFFFF也就是 UINT32_MAX（十进制 4294967295）。
            if(sleep_time_ms == LV_NO_TIMER_READY){
                sleep_time_ms =  LV_DEF_REFR_PERIOD;//对于PC 模拟器 / 桌面环境，设置休眠时间为33ms，也就是刷新率1000ms/33ms≈30fps
                //嵌入式系统（有屏幕动画）设为20~50ms，平衡流畅度与 CPU 占用；低功耗设备（少动画）设为100~200ms，节能优先，不需要频繁刷新；
            }

            // 跨平台的延时（sleep）处理。
            #ifdef _MSC_VER // Visual Studio在Windows下编译的情况下会定义这个宏，以此判断是否为Windows平台
                Sleep(sleep_time_ms);//Sleep是 Windows API 的休眠函数。单位是 毫秒（ms）。
            #else // 否则即为Unix/Linux/MacOS
                usleep(sleep_time_ms * 1000);//usleep为POSIX 标准（Unix/Linux） 的休眠函数，参数单位微秒，此处乘以 1000 把毫秒转为微秒。
            #endif
        }

        return 0;
    }
#endif

/**********************
 *   STATIC FUNCTIONS
 **********************/
